// Copyright (C) 2005 Taylor L. Riché <riche@cs.utexas.edu>
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// 	$Id: Container.cc 374 2006-02-08 02:12:59Z richetl $	
//

#include "Container.hh"
#include "Module.hh"
#include "Composable.hh"
#include "Function.hh"

using namespace lee;

void
Container::setCMap(std::map<pthread_t, CourierUnit*> const & cmap)
{
  for(std::map<std::string, Composable*>::iterator i = composableMap.begin();
      i != composableMap.end(); i++) {
    Subscription * sub;
    if((sub = dynamic_cast<Subscription *>(i->second)) != NULL) {
      sub->setMap(&cmap);
    }
    Module * mod;
    if((mod = dynamic_cast<Module *>(i->second)) != NULL) {
      if(mod != this) {
	mod->setCMap(cmap);
	mod->registerSubs(sub);
      }
    }
  }
  return;
}


Composable * 
Container::getNextComposable(std::string composableName, int exitPoint) 
{
  Synchronized::Scope mutex(this);
  std::map<int, Composable *> * target;
  while(appGraph.count(composableName) == 0) {
    wait();
  }
  while(appGraph[composableName] == NULL) {
    wait();
  }
  while(appGraph[composableName]->count(exitPoint) == 0) {
    // FIXME: Make this trigger a packet drop
    wait();
  }
  target = appGraph[composableName];
  return (*target)[exitPoint];
}

void
Container::registerComposableSubs(Composable * comp)
{
  Subscription * sub = NULL;
  if((sub = dynamic_cast<Subscription *>(comp)) != NULL) {
    assert(sub != NULL);
    sub->registerSubs(dynamic_cast<Subscription *>(this));
  }
  return;
}

void
Container::dealWithModule(Module * m, Container * c)
{
  Synchronized::Scope mutex(this);
  m->formInnerComponents(c);
  m->setMapSet(true);
  notifyAll();
  return;
}
